package com.example.proxy.client;

import com.example.proxy.service.OrderService;
import com.example.proxy.service.OrderServiceImpl;
import com.example.proxy.service.TimerInvocationHandler;
import com.example.proxy.util.ProxyUtil;

import javax.print.attribute.standard.OrientationRequested;
import java.lang.reflect.Proxy;

/**
 * ClassName:Client
 * Package:com.example.proxy.client
 * Description:
 *
 * @Author:ZhangXin
 * @Create:2023/5/10-15:56
 * @Version:v1.0
 */
//客户端程序
public class Client {
    public static void main(String[] args) {
        //创建目标对象
        OrderService target = new OrderServiceImpl();
        //创建静态对象
        //Object proxyObj = Proxy.newProxyInstance(类加载器,代理类要实现的接口,调用处理器);
        /**
         newProxyInstance-新建代理对象(也就是说,通过调用这个方法可以创建代理对象)
         newProxyInstance()方法执行,做了两件事情
         1.在内存中动态的生成了一个代理类的字节码 class
         2.new对象,通过内存中生成的代理类这个代码,实例化了代理对象

         newProxyInstance()方法的三个参数

         1.ClassLoader loader(类加载器)在内存中生成的字节码也是class文件,要执行也得先加载到内存当中,加载类就需要类加载器,所以这里需要指定类加载器
         并且JDK要求,目标类的类加载器必须和代理类的类加载器使用同一个

         2.Class<?>[] interfaces
         代理类和目标类要实现同一个接口或同一些接口

         3.InvocationHandler h(调用处理器,是一个接口)
         在调用处理器接口中编写的就是增强代码
         既然是接口,就要写接口的实现类

         注意:代理对象和目标对象实现的接口一样,所以可以向下转型
         */
        //Object proxyObj = Proxy.newProxyInstance(类加载器,代理类要实现的接口,调用处理器);
//        Proxy.newProxyInstance(target.getClass().getClassLoader(),
//                target.getClass().getInterfaces(),
//                new TimerInvocationHandler(target));
        OrderService proxyObj = (OrderService) ProxyUtil.newProxyInstance(target);//工具类封装
        //调用代理对象的代理方法
        //注意:调用代理对象的代理方法的时候,如果你要做增强的话,目标对象的目标方法的保证执行
        proxyObj.detail();
        proxyObj.modify();
        proxyObj.generate();

        String name = proxyObj.getName();
        System.out.println(name);
    }
}
